package com.k.kpp.aop.log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 切面
 *
 * 包下 所有类  所有方法
 * @Pointcut("execution(* com.k.kpp.web.controller.*.*(..))")
 *
 * 包下 所有类  save方法
 * @Pointcut("execution(* com.k.kpp.web.controller.*.save(..))")
 *
 * 包下 所有类  save 或 update 方法
 * @Pointcut("execution(* com.k.kpp.web.controller.*.save(..))"+
 *             "|| execution(* com.k.kpp.web.controller.*.update(..))")
 *
 */
@Aspect
@Component
public class ControllerLogAspect {
    @Pointcut("execution(* com.k.kpp.web.controller.*.save(..))" +
            "|| execution(* com.k.kpp.web.controller.*.update(..))" +
            "|| execution(* com.k.kpp.web.controller.*.delete(..))" +
            "|| execution(* com.k.kpp.web.controller.*.uploadFileTest(..))"
    )
    public void pointCut() {
    }

    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("@Before通知执行");
    }

    @AfterReturning(value = "pointCut()", returning = "result")
    public void doAfterReturningAdvice1(JoinPoint joinPoint, Object result) {
        System.out.println("@AfterReturning :"+result);
    }

    @AfterReturning("pointCut()")
    public void afterRet(JoinPoint point){
        System.out.println("@AfterReturning:");
        String serviceName = point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName();
        System.out.println("@AfterReturning:"+serviceName);
        Object[] args = point.getArgs();
        Object obj0 = args[0];
        System.out.println(obj0);
    }

    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void doAfterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {
        System.out.println(joinPoint.getSignature().getName());
        if (exception instanceof NullPointerException) {
            System.out.println("@AfterThrowing: 发生了空指针异常!!!!!");
        }
    }

    @After(value = "pointCut()")
    public void doAfterAdvice(JoinPoint joinPoint) {
        System.out.println("@After: 后置通知执行了!");
    }

    @Around(value = "pointCut()")
    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("@Around: 环绕通知：" + proceedingJoinPoint.getSignature().toString());
        Object obj = null;
        try {
            obj = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw throwable;
        } finally {
            System.out.println("@Around: 环绕通知执行结束");
        }
        return obj;
    }
}
